#ifndef SUBSTRACT_NETWORK_H
#define SUBSTRACT_NETWORK_H

#include "network.h"
#include "virtual_network.h"

#include <climits>
#include <cstring>
#include <vector>
using namespace std;

//used by shortest path algorithm
struct V{
	int d;
	int pi;
};

struct ScheduleElement{
	int vn_id;
	int real_prize;
	VirtualNetwork* vn;
};


bool mostPrizeFirst( struct ScheduleElement e1, struct ScheduleElement e2 ){
	return e1.real_prize > e2.real_prize;
}

int greedyMoreProcessingNodeFirst( const void* n1, const void* n2 ){
	if (((struct Node*)n2)->processing == ((struct Node*)n1)->processing )
		return ((struct Node*)n1)->id - ((struct Node*)n2)->id;
	else
		return ((struct Node*)n2)->processing - ((struct Node*)n1)->processing;
}

int compareIds( const void* n1, const void* n2 ){
	return ((struct Node*)n1)->id - ((struct Node*)n2)->id;
}


class SubstractNetwork : public Network{
	public:
		enum PrioritySystem{ MostPrizeFirst, ArrivalOrder };
		enum AllocationSystem{ Greedy, TabuSearch };
		
		SubstractNetwork( const char*, const char* );
		SubstractNetwork( const SubstractNetwork& );
		~SubstractNetwork();
		
		void setPrioritySystem( PrioritySystem );
		void setAllocationSystem( AllocationSystem );
		int getSumPrizesAttendedRequests();
		int getTotalAttendedRequests();
		void pushInScheduleQueue( VirtualNetwork*, int );
		void popFromScheduleQueue( int );
		void deallocateVirtualNetwork( int );
		void scheduler();
		
	private:
		bool verbose;
		
		void updateRealPrizes();
		void sortVirtualNetworks();
		bool allocateVirtualNetwork( ScheduleElement );
		
		bool greedyMethod( ScheduleElement );
		bool tabuSearch( ScheduleElement );
		
		bool buildPath( int, int, list<int>**, int );
		
		
		
		list< struct ScheduleElement > schedule_queue;
		list< struct ScheduleElement > active_vns;
		PrioritySystem priority_system;
		AllocationSystem allocation_system;
		
		int sum_prizes_attended_requests;
		int total_attended_requests;
};

#include "tabu_search.h"

#include "substract_network.cpp"

#endif